package com.jxpanda.commons.base;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.IService;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.BinaryOperator;
import java.util.function.Function;

/**
 * @author Panda
 */
public interface Service<T extends Entity> extends IService<T> {

    /**
     * 创建一条数据，同时记录创建者ID
     *
     * @param entity     要保存的对象
     * @param executorId 执行这个操作的人的ID，如果执行创建操作，则会同时设置创建者ID
     * @return 保存是否成功
     */
    boolean save(T entity, String executorId);

    /**
     * 更新一条数据，同时记录更新者ID
     *
     * @param entity     要保存的对象
     * @param executorId 执行这个操作的人的ID，如果执行创建操作，则会同时设置创建者ID
     * @return 保存是否成功
     */
    boolean updateById(T entity, String executorId);

    /**
     * 保存或更新一条数据
     *
     * @param entity     要保存的对象
     * @param executorId 执行这个操作的人的ID，如果执行创建操作，则会同时设置创建者ID
     * @return 保存是否成功
     */
    boolean saveOrUpdate(T entity, String executorId);

    boolean saveBatch(Collection<T> entityList, String executorId);

    boolean saveOrUpdateBatch(Collection<T> entityList, String executorId);

    boolean remove(String executorId, UpdateWrapper<T> updateWrapper);

    boolean removeById(Serializable id, String executorId);

    boolean removeByIds(Collection<? extends Serializable> idList, String executorId);

    /**
     * 物理删除，利用mybatis-plus的wrapper删除
     *
     * @param wrapper Wrapper对象
     * @return 删除是否成功
     */
    boolean destroy(Wrapper<T> wrapper);

    /**
     * 物理删除，基于主键ID删除
     *
     * @param id 主键ID
     * @return 删除是否成功
     */
    boolean destroyById(Serializable id);

    /**
     * 物理删除，用主键ID批量删除
     *
     * @param ids 主键ID的列表
     * @return 删除是否成功
     */
    boolean destroyByIds(Collection<? extends Serializable> ids);

    /**
     * 查询数据是否存在
     *
     * @param id id
     * @return 是否存在（true表示存在，false表示不存在）
     */
    boolean isExisting(Serializable id);

    /**
     * 查询数据是否存在
     *
     * @param wrapper Wrapper对象
     * @return 是否存在（true表示存在，false表示不存在）
     */
    boolean isExisting(Wrapper<T> wrapper);

    /**
     * 基于ID批量查询列表，然后以id作为key,数据对象作为value，映射成为一个Map结构
     *
     * @param ids id的集合
     * @return 数据映射的Map结构
     */
    Map<? extends Serializable, T> associateById(Collection<? extends Serializable> ids);

    /**
     * 查询列表，然后基于keySelector函数映射成一个map结构
     *
     * @param keySelector key的映射函数，lambda表达式
     * @param wrapper     Wrapper对象
     * @return 数据映射的Map结构
     */
    <K> Map<K, List<T>> groupBy(Function<? super T, ? extends K> keySelector, Wrapper<T> wrapper);

    /**
     * 查询列表，然后基于keySelector函数映射成一个map结构
     * 这个函数没有提供值选择器入参，这个函数断言同一个key下不会有重复的对象
     * 即便有重复对象，内部处理机制也是默认使用排序规则下的第一条数据
     *
     * @param keySelector key的映射函数，lambda表达式
     * @param wrapper     Wrapper对象
     * @return 数据映射的Map结构
     */
    <K> Map<K, T> associateBy(Function<? super T, ? extends K> keySelector, Wrapper<T> wrapper);

    /**
     * 查询列表，然后基于keySelector函数映射成一个map结构
     *
     * @param keySelector   key的映射函数，lambda表达式
     * @param valueSelector value的选择函数（当查询出来的对象在同一key值下重复的时候，这个用来选择用哪个对象），lambda表达式
     * @param wrapper       Wrapper对象
     * @return 数据映射的Map结构
     */
    <K> Map<K, T> associateBy(Function<? super T, ? extends K> keySelector, BinaryOperator<T> valueSelector, Wrapper<T> wrapper);

    /**
     * 求和函数
     *
     * @param field   字段
     * @param wrapper Wrapper对象
     * @return 求和的值，默认返回0
     */
    BigDecimal sum(String field, Wrapper<T> wrapper);

    /**
     * 使用Seeker分页查询
     *
     * @param seeker 查询对象
     * @return 分页数据列表
     */
    Pagination<T> pagination(Seeker<T> seeker);

    /**
     * 使用Seeker查询列表（不分页）
     *
     * @param seeker 查询对象
     * @return 对象列表
     */
    List<T> listBySeeker(Seeker<T> seeker);

    /**
     * 使用seeker查询一条
     *
     * @param seeker 查询对象
     * @return 对象
     */
    T getBySeeker(Seeker<T> seeker);


}
